<!--
 * @Author       : xiangmin
 * @File         : 导航切换咯
 * @Date         : 2023-06-08 23:20:01
 * @LastEditors  : xiangmin
 * @LastEditTime : 2023-06-11 12:34:20
-->

<template>
	<div class="nav-box">
		<div
			v-for="item in nav"
			:key="item.value"
			:class="[(item.value === active || selected === item.value) && 'active', 'nav-item']"
			@click="handleNavClick(item, $event)"
		>
			{{ item.label }}
		</div>
		<div class="active-bar"></div>
	</div>
</template>

<script setup lang="ts">
type Active = number | string | undefined
interface Nav {
	label: string
	value: Active
	[key: string]: unknown
}

const selected = ref<Active>('')
const active = defineModel<Active>({ default: '', required: false })
const props = defineProps<{
	defaultSelected?: Active
	nav: Nav[]
}>()
const emits = defineEmits<{
	change: [data: Nav]
}>()

watch(
	() => props.defaultSelected,
	value => (selected.value = value),
	{ immediate: true }
)

const left = ref('')
const width = ref('')
const handleNavClick = (item: Nav, event: MouseEvent) => {
	const { offsetLeft, offsetWidth } = event.target as HTMLDivElement
	left.value = `${offsetLeft}px`
	width.value = `${offsetWidth}px`
	selected.value = item.value
	active.value = item.value
	emits('change', item)
}

onMounted(() => {
	const { offsetLeft, offsetWidth } = document.querySelector('.active') as HTMLDivElement
	left.value = `${offsetLeft}px`
	width.value = `${offsetWidth}px`
})
</script>

<style lang="less" scoped>
.nav-box {
	display: flex;
	gap: 40px;
	position: relative;

	// 这是选中状态滑动的效果，下面的那个伪类是缩放的效果
	.active-bar {
		height: 2.5px;
		position: absolute;
		bottom: 0;
		left: v-bind('left');
		width: v-bind('width');
		background-color: var(--main-color);
		transition: left 0.15s cubic-bezier(0.645, 0.045, 0.355, 1);
	}

	.nav-item {
		height: 40px;
		display: flex;
		align-items: center;
		font-size: 16px;
		cursor: pointer;
		position: relative;

		&:hover {
			color: var(--main-color);
		}

		// &::after {
		// 	position: absolute;
		// 	content: '';
		// 	height: 2.5px;
		// 	left: 0px;
		// 	right: 0px;
		// 	bottom: 0;
		// 	background: var(--main-color);
		// 	opacity: 0;
		// 	transform: scaleX(0);
		// 	transition: transform 0.2s cubic-bezier(0.645, 0.045, 0.355, 1),
		// 		opacity 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
		// }

		&.active {
			font-weight: bold;
			color: var(--main-color);

			// &::after {
			// 	transform: scaleX(1);
			// 	opacity: 1;
			// }
		}
	}
}
</style>
